package org.de.maeyer.statistic;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.de.maeyer.unit.Unit;

/**
 * @author Peter De Maeyer
 */
public interface Statistics {
	
	Class getValueClass();
	
	String getName();
	
	Unit getUnit();
	
	boolean hasCount();
	
	long getCount();
	
	boolean hasLastValue();
	
	Object getLastValue();
	
	double getLastValue(Unit unit);
	
	boolean hasExtrema();
	
	Object getMinimum();
	
	double getMinimum(Unit unit);
	
	Object getMaximum();
	
	double getMaximum(Unit unit);
	
	boolean hasMean();
	
	double getMean();
	
	boolean hasVariance();
	
	double getSampleVariance();
	
	double getSampleStdDev();
	
	double getPopulationVariance();
	
	double getPopulationStdDev();
	
	boolean hasElapsedTime();
	
	/**
	 * @return the time unit of the elapsed time returned by {@link #getElapsedTime()}.
	 * @see #hasElapsedTime()
	 */
	Unit getTimeUnit();
	
	/**
	 * @return the elapsed time in the unit specified by {@link #getTimeUnit()}.
	 * @see #hasElapsedTime()
	 */
	long getElapsedTime();
	
	double getElapsedTime(Unit timeUnit);
	
	boolean hasTotal();
	
	/**
	 * @see #hasTotal()
	 */
	Number getTotal();
	
	/**
	 * @return the total in the specified unit.
	 * @see #hasTotal()
	 * @throws ArithmeticException if the specified unit is incompatible with the unit returned by {@link #getUnit()}.
	 */
	double getTotal(Unit unit);
	
	/**
	 * @return <code>true</code> iff both {@link #hasCount()} and {@link #hasElapsedTime()} return <code>true</code>. 
	 */
	boolean hasRate();
	
	double getRate();
	
	double getRate(Unit timeUnit);
	
	double getRate(TimeUnit timeUnit);
	
	/**
	 * @return <code>true</code> iff both {@link #hasTotal()} and {@link #hasElapsedTime()} return <code>true</code>. 
	 */
	boolean hasThroughput();
	
	double getThroughput();
	
	double getThroughput(Unit unit, Unit timeUnit);
	
	double getThroughput(Unit unit, TimeUnit timeUnit);
	
	/**
	 * @return <code>true</code> iff the statistics include histogram data.
	 */
	boolean hasHistogram();
	
	/**
	 * @return the list of disjoint histogram categories.
	 * @see #hasHistogram()
	 */
	List<Category> getCategories();
	
	/**
	 * @return the indexes of the mode categories in the list returned by {@link #getCategories()}. The mode category is the category with the highest density.
	 * @see #hasHistogram()
	 */
	int[] getModeCategoryIndexes();
}
